package com.nowcoder.community.quartz;

import com.nowcoder.community.pojo.DiscussPost;
import com.nowcoder.community.service.DiscussPostService;
import com.nowcoder.community.service.ElasticsearchService;
import com.nowcoder.community.service.LikeService;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.RedisKeyUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

//定义一个任务
public class PostScoreRefrushJob implements Job, CommunityConstant{

    private static final Logger logger = LoggerFactory.getLogger(PostScoreRefrushJob.class);

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DiscussPostService discussPostService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private ElasticsearchService elasticsearchService;

    //牛客纪元（牛客成立时间）
    private static final Date epoch;

    static{
        try {
            epoch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                    .parse("2014-08-01 00:00:00");
        } catch (ParseException e) {
            throw new RuntimeException("初始化牛客纪元失败！", e);
        }
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String redisKey = RedisKeyUtil.getPostScoreKey();

        //将redisKey对应的所有的value（帖子id）添加到容器中
        BoundSetOperations boundSetOperations = redisTemplate.boundSetOps(redisKey);

        if(boundSetOperations.size() == 0){
            logger.info("[任务取消]，没有要刷新的帖子！");
            return;
        }

        logger.info("[任务开始]，正在刷新帖子分数！" + boundSetOperations.size());

        while(boundSetOperations.size() > 0){
            this.refrush((Integer)boundSetOperations.pop());
        }

        logger.info("[任务结束]，帖子分数刷新完毕！");

    }

    private void refrush(int postId){
        DiscussPost discussPost = discussPostService.findDiscussPostById(postId);

        if(discussPost == null){
            logger.error("该帖子不存在: id = " + postId);
            return;
        }

        //是否是精华
        boolean wonderful = discussPost.getStatus() == 1;

        //评论数量
        int commentCount = discussPost.getCommentCount();

        //点赞数量
        long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, postId);

        //计算权重
        double w = (wonderful ? 75 : 0) + commentCount * 10 + likeCount * 2;

        //分数 = 帖子权重 + 距离天数(1000ms * 3600 * 24)
        double score = Math.log10(Math.max(w, 1)) +
                (discussPost.getCreateTime().getTime() - epoch.getTime()) / (1000 * 3600 * 24);

        //更新帖子分数
        discussPostService.updateScore(postId, score);

        //同步ES中的数据
        discussPost.setScore(score);
        //添加到ES中（就是更新分数）
        elasticsearchService.saveDiscussPost(discussPost);

    }
}
